import { ConfigEnv, loadEnv, UserConfig, Plugin } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import path from 'path'
import dayjs from 'dayjs'

// 插件导入
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import {
	ElementPlusResolver,
	VantResolver,
} from 'unplugin-vue-components/resolvers'
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import UnoCSS from 'unocss/vite'
import { viteMockServe } from 'vite-plugin-mock'
import VueSetupExtend from 'vite-plugin-vue-setup-extend'
import viteCompression from 'vite-plugin-compression'
import { visualizer } from 'rollup-plugin-visualizer'
import { createHtmlPlugin } from 'vite-plugin-html'
import mockDevServerPlugin from 'vite-plugin-mock-dev-server'
import legacy from '@vitejs/plugin-legacy'
import { VitePWA } from 'vite-plugin-pwa'

// 当前工作目录路径
const root = process.cwd()
const pathSrc = path.resolve(__dirname, 'src')

export default ({ mode }: ConfigEnv): UserConfig => {
	const env = loadEnv(mode, root)
	const timestamp = dayjs().format('YYYYMMDDHHmmss') // 生成时间戳
	const isProduction = env.VITE_NODE_ENV === 'production'
	const useMock = env.VITE_APP_USE_MOCK === 'true'
	const enablePWA = env.VITE_ENABLE_PWA === 'true'
	const enableAnalyze = env.VITE_ANALYZE === 'true'

	return {
		// 基础路径
		base: env.VITE_BASE_URL || './',

		// 解析配置
		resolve: {
			alias: {
				'~': path.resolve(__dirname, './'),
				'@': path.resolve(__dirname, './src'),
				'@api': path.resolve(__dirname, 'src/api'),
				'@views': path.resolve(__dirname, 'src/views'),
				'@utils': path.resolve(__dirname, 'src/utils'),
				'@comp': path.resolve(__dirname, 'src/components'),
				'@assets': path.resolve(__dirname, 'src/assets'),
			},
			extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
		},

		// 插件配置
		plugins: [
			// Vue 相关插件
			vue(),
			vueJsx(),
			VueSetupExtend(), // 允许 setup 语法糖上添加组件名属性

			// 自动导入插件
			AutoImport({
				imports: ['vue', 'vue-router'], // 添加 vue-router
				eslintrc: {
					enabled: true,
					filepath: './.eslintrc-auto-import.json',
				},
				resolvers: [ElementPlusResolver(), IconsResolver({})],
				vueTemplate: true,
				dts: path.resolve(pathSrc, 'types', 'auto-imports.d.ts'),
			}),

			// 组件自动导入
			Components({
				resolvers: [
					ElementPlusResolver(),
					VantResolver(),
					IconsResolver({
						enabledCollections: ['ep'],
					}),
				],
				dts: path.resolve(pathSrc, 'types', 'components.d.ts'),
			}),

			// 图标插件
			Icons({ autoInstall: true }),

			// SVG 图标插件
			createSvgIconsPlugin({
				iconDirs: [
					path.resolve(root, 'src/assets/icons'),
					path.resolve(root, 'src/icons/svg'),
				],
				symbolId: 'icon-[dir]-[name]',
			}),

			// UnoCSS 原子化 CSS
			UnoCSS(),

			// Mock 服务
			useMock
				? viteMockServe({
						mockPath: './src/mock',
						logger: true,
					})
				: null,

			// HTML 插件
			createHtmlPlugin({
				inject: {
					data: {
						BUILD_TIMESTAMP: timestamp,
						ENABLE_ERUDA: env.VITE_ENABLE_ERUDA || 'false',
						CSP_NONCE: Math.random().toString(36).substring(2),
					},
				},
			}),

			// 压缩插件
			isProduction &&
				viteCompression({
					ext: '.gz',
					threshold: 10240,
					algorithm: 'gzip',
					deleteOriginFile: false,
				}),

			// PWA 插件
			enablePWA &&
				VitePWA({
					registerType: 'autoUpdate',
					workbox: {
						globPatterns: ['**/*.{js,css,html,ico,png,svg}'],
						maximumFileSizeToCacheInBytes: 10 * 1024 * 1024,
					},
					manifest: {
						name: env.VITE_APP_TITLE || 'My App',
						short_name: env.VITE_APP_SHORT_NAME || 'App',
						theme_color: '#ffffff',
						background_color: '#ffffff',
						display: 'standalone',
						scope: '/',
						start_url: '/',
						icons: [
							{
								src: '/pwa-192x192.png',
								sizes: '192x192',
								type: 'image/png',
							},
							{
								src: '/pwa-512x512.png',
								sizes: '512x512',
								type: 'image/png',
							},
						],
					},
				}),

			// 打包分析
			enableAnalyze &&
				visualizer({
					template: 'treemap',
					filename: './dist/bundle-analysis.html',
					gzipSize: true,
					brotliSize: true,
					open: true,
				}),

			// 兼容性处理
			legacy({
				targets: ['defaults', 'not IE 11'],
				modernPolyfills: true, // 添加现代浏览器polyfill
			}),
		].filter(Boolean) as Plugin[], // 过滤掉 false 值

		// CSS 配置
		css: {
			modules: {
				scopeBehaviour: 'local',
				generateScopedName: isProduction
					? '[hash:base64:8]'
					: '[name]__[local]___[hash:base64:5]',
			},
			preprocessorOptions: {
				scss: {
					javascriptEnabled: true,
				},
			},
			devSourcemap: true, // 开发环境启用 sourcemap
		},

		// 开发服务器配置
		server: {
			host: '0.0.0.0',
			port: Number(env.VITE_APP_PORT) || 5173,
			open: true,
			// 安全头配置（响应给浏览器的）

			proxy: {
				[env.VITE_APP_BASE_API || '/api']: {
					target: `http://116.148.212.135:9003`,
					changeOrigin: true,
					rewrite: (path) =>
						path.replace(new RegExp(`^${env.VITE_APP_BASE_API || '/api'}`), ''),
					ws: true,
				},
			},
			hmr: {
				overlay: false, // 禁用错误覆盖层（与 CSP 兼容性更好）
			},
		},

		// 构建配置
		build: {
			minify: isProduction ? 'terser' : 'esbuild',
			assetsDir: 'assets',
			outDir: 'dist',
			sourcemap: env.VITE_SOURCE_MAP === 'true',
			cssTarget: 'chrome80',
			terserOptions: {
				compress: {
					drop_console: isProduction,
					drop_debugger: isProduction,
				},
			},
			target: ['es2020', 'edge88', 'firefox78', 'chrome87', 'safari14'],
			modulePreload: { polyfill: false },
			cssCodeSplit: true,
			chunkSizeWarningLimit: 3000,
			rollupOptions: {
				input: 'index.html',
				output: {
					chunkFileNames: 'static/js/[name]-[hash].js',
					entryFileNames: 'static/js/[name]-[hash].js',
					assetFileNames: (assetInfo: any) => {
						const extType = assetInfo.name.split('.').pop()?.toLowerCase() || ''
						if (/css/i.test(extType)) {
							return 'static/css/[name]-[hash][extname]'
						}
						if (/png|jpe?g|svg|gif|webp/i.test(extType)) {
							return 'static/img/[name]-[hash][extname]'
						}
						if (/woff2?|ttf|eot/i.test(extType)) {
							return 'static/fonts/[name]-[hash][extname]'
						}
						return 'static/assets/[name]-[hash][extname]'
					},
					manualChunks: (id: string) => {
						if (id.includes('node_modules')) {
							if (
								id.includes('vue') ||
								id.includes('vue-router') ||
								id.includes('pinia')
							) {
								return 'vendor-vue'
							}
							if (id.includes('element-plus')) {
								return 'vendor-element-plus'
							}
							if (id.includes('vant')) {
								return 'vendor-vant'
							}
							if (
								id.includes('axios') ||
								id.includes('lodash') ||
								id.includes('dayjs')
							) {
								return 'vendor-utils'
							}
							if (id.includes('echarts')) {
								return 'vendor-charts'
							}
							return 'vendor-others'
						}
					},
				},
			},
		},
	}
}
